package com.credithc.signature.common.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.CharsetUtils;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Map;

/**
 * 描述：上传PDF工具类<br/>
 * 作者：sunyang
 * 创建：2019/6/4 10:57
 * 版本：v1.0.0<br/>
 */
@Slf4j
public class HttpUploadUtil {

    /**
     * @param filePath  要上传的文件的路径
     * @param requestNo 请求流水号
     * @return void
     * @throws
     * @Title: upload
     * @Description: 文件上传
     */
    public static String upload(String filePath, String name, String requestNo, String url) throws Exception {
        String fsId = null;
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        HttpEntity responseEntity = null;
        try {
            httpClient = HttpClientUtils.getHttpClient();

            // 把一个普通参数和文件上传给下面这个地址
            HttpPost httpPost = new HttpPost(url);

            HttpEntity reqEntity = generateHttpEntity(filePath, name, requestNo);

            httpPost.setEntity(reqEntity);

            log.debug("发起请求的地址为：" + httpPost.getRequestLine());
            // 发起请求 并返回请求的响应
            httpResponse = httpClient.execute(httpPost);

            // 打印响应状态
            log.debug("获取响应状态为：" + httpResponse.getStatusLine());
            // 获取响应对象
            responseEntity = httpResponse.getEntity();
            fsId = getFsid(responseEntity);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (responseEntity != null) {
                // 销毁
                EntityUtils.consume(responseEntity);
            }
            if (httpResponse != null) {
                httpResponse.close();
            }
        }
        return fsId;
    }

    private static String getFsid(HttpEntity responseEntity) throws Exception {
        if (responseEntity == null) {
            log.error("文件上传文件系统失败:服务返回空响应");
            throw new Exception("文件上传文件系统失败:服务返回空响应");
        }
        // 打印响应内容
        String result = EntityUtils.toString(responseEntity, Charset.forName("UTF-8"));
        JSONObject json = JSONObject.parseObject(result);
        log.debug("响应报文为：" + json.toJSONString());
        Map<String, String> data = null;
        if (json.get("result").equals("1")) {
            data = (Map<String, String>) json.get("data");
            if (data.get("status").equals("1")) {
                return data.get("fsId");
            } else {
                log.error("文件上传文件系统失败:{}", data.get("message"));
                throw new Exception("文件上传文件系统失败:" + data.get("message"));
            }
        } else {
            log.error("文件上传文件系统失败:{}", json.get("errorMsg").toString());
            throw new Exception("文件上传文件系统失败:" + json.get("errorMsg").toString());
        }
    }

    private static HttpEntity generateHttpEntity(String filePath, String name, String requestNo) throws UnsupportedEncodingException {
        // 把文件转换成流对象FileBody
        File file = new File(filePath);
        FileBody bin = new FileBody(file);
        //调用者业务ID
        StringBody businessId = new StringBody(requestNo, ContentType.create("text/plain", Consts.UTF_8));
        //调用者系统ID
        StringBody systemId = new StringBody("signature", ContentType.create("text/plain", Consts.UTF_8));
        //文件类型(注* 此处上传pdf类型文件，fileType参数填写为 doc)
        StringBody fileType = new StringBody("doc", ContentType.create("text/plain", Consts.UTF_8));
        //文件原始名称
        StringBody fileName = new StringBody(name, ContentType.create("text/plain", Consts.UTF_8));
        //从文件名，非图片类型不需要裁剪 缩放的文件 此参数为空
        StringBody slaveName = new StringBody("", ContentType.create("text/plain", Consts.UTF_8));
        //以浏览器兼容模式运行，防止文件名乱码。
        return MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                .addPart("file", bin)
                .addPart("systemId", systemId)
                .addPart("fileType", fileType)
                .addPart("fileName", fileName)
                .addPart("slaveName", slaveName)
                .addPart("businessId", businessId).setCharset(CharsetUtils.get("UTF-8")).build();
    }

    /**
     * 下载文件
     *
     * @param fileId
     * @return
     */
    public static void download(String downloadUrl, String fileId, String savePath) {
        if (StringUtils.isNotEmpty(fileId)) {
            try {
                byte[] bytes = HttpClientProxy.get(downloadUrl, "?fsId=" + fileId + "&" + "openType=download");
                FileOutputStream out = new FileOutputStream(savePath);
                out.write(bytes);
                out.close();
                log.info("文件下载成功......");
            } catch (IOException e) {
                log.error("文件下载发生异常......", e);
            }
        }
    }

    /**
     * @param downloadUrl
     * @return
     */
    public static byte[] download(String downloadUrl) {
        if (StringUtils.isNotEmpty(downloadUrl)) {
            try {
                byte[] bytes = HttpClientProxy.get(downloadUrl);
                log.info("文件下载成功......");
                return bytes;
            } catch (IOException e) {
                log.error("文件下载发生异常......", e);
            }
        } else {
            log.error("文件下载发生异常,下载地址不能为空");
        }
        return null;
    }
}
